﻿// Copyright (c) 2008 Interact Software Ltd.

// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 

// Dynamic Bitmap Generation for Silverlight
// =========================================
// See http://www.codeplex.com/SlDynamicBitmap for details.

using System;

namespace InteractSw.GenerateBitmap
{
    /// <summary>
    /// Helpers for copying data around.
    /// </summary>
    class CopyUtilities
    {
        /// <summary>
        /// Copy as much data as possible for a read operation.
        /// </summary>
        /// <param name="targetBuffer">Buffer to put data being read.</param>
        /// <param name="targetOffset">Position from which to start putting read data.</param>
        /// <param name="targetEnd">Offset at which no more data must be written.</param>
        /// <param name="source">Buffer from which data is being copied.</param>
        /// <param name="sourceOffset">Offset from which to start copying.</param>
        /// <returns>Number of bytes copied.</returns>
        /// <remarks>
        /// We frequently end up needing to copy data around, and the size of the source and
        /// target buffers don't necessarily match up neatly. The simple approach is to copy
        /// one byte at a time, but that has dreadful perf. This works out the largest amount
        /// that can be copied while still fitting into the remaining space, and without
        /// attempting to copy more data than there is.
        /// 
        /// The slightly peculiar bunch of arguments comes from the fact that this fell out
        /// of a refactoring exercise. It's not a wonderfully useful general-purpose method.
        /// </remarks>
        public static int WriteAsMuchDataAsPossible(byte[] targetBuffer, int targetOffset, int targetEnd, byte[] source, int sourceOffset)
        {
            int spaceInTarget = targetEnd - targetOffset;
            int spaceInSource = source.Length - sourceOffset;
            int toCopy = Math.Min(spaceInSource, spaceInTarget);
            Array.Copy(source, sourceOffset, targetBuffer, targetOffset, toCopy);
            return toCopy;
        }
    }
}
